﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "GcmpModelInterface.h"
#include "CollaborationScope.h"

namespace gcmp
{
    class UniIdentity;
    class ElementId;
    class IGraphicsStyleData;
    class ILineTypeData;
    class IFillPatternData;
    
    /// \brief 图形样式管理器
    class GCMP_MODEL_INTERFACE_EXPORT IGraphicsStyleManager
    {
    public:
        /// \brief 析构函数
        virtual ~IGraphicsStyleManager();

        /// \brief 通过类别的 UniIdentity 获取其图形样式
        /// \param categoryUid 类别的 UniIdentity
        /// \return 图形样式的 id
        virtual ElementId GetGraphicsStyleIdByCategoryUid(const UniIdentity& categoryUid) const = 0;

        /// \brief 为某个类别创建图形样式
        /// 
        /// 内建类别的图形样式不需要用户创建，系统会自动创建，
        /// 只有那些非内建的针对类别的图形样式才需要用户调用此函数来创建，且不能重复创建
        /// \param categoryUid 类别的 UniIdentity
        /// \param graphicsStyleData 图形样式的初始值 
        /// \return 图形样式的id
        virtual ElementId CreateGraphicsStyleForCategory(const UniIdentity& categoryUid, const IGraphicsStyleData& graphicsStyleData) = 0;

        /// \brief 通过类别的 UniIdentity 获取其剖切面前景Elements的图形样式
        /// \param categoryUid 类别的 UniIdentity
        /// \return 图形样式的 id
        virtual ElementId GetForegroundGraphicsStyleIdByCategoryUid(const UniIdentity& categoryUid) const = 0;

        /// \brief 为某个类别创建剖切面前景Elements的图形样式
        ///
        /// 如果类别没有基础图形样式，则不能创建前景图形样式。类别的前景图形样式默认与类别的基础图形样式保持一致
        /// 用户可以调用此函数来创建新的前景图形样式，但不能重复创建
        /// \param categoryUid 类别的 UniIdentity
        /// \param foregroundElementGraphicsStyleData 前景图形样式的初始值
        /// \return 图形样式的id
        virtual ElementId CreateForegroundGraphicsStyleForCategory(const UniIdentity& categoryUid, const IGraphicsStyleData& foregroundElementGraphicsStyleData) = 0;

        /// \brief 通过类别的 UniIdentity 获取其图形样式
        /// \param categoryUid 类别的 UniIdentity
        /// \param context 协同基本信息。包括项目Id、协同影响范围、专业（在影响范围为CollaborationScope::Specialty时有效）
        /// \return 图形样式的 id
        virtual ElementId GetGraphicsStyle(
            const UniIdentity& categoryUid,
            const CollaborationContext& context
        ) const = 0;

        /// \brief 为某个类别创建图形样式
        /// \param categoryUid 类别的 UniIdentity
        /// \param graphicsStyleData 图形样式的初始值 
        /// \param context 协同基本信息。包括项目Id、协同影响范围、专业（在影响范围为CollaborationScope::Specialty时有效）
        /// \return 图形样式的id
        virtual ElementId CreateGraphicsStyle(
            const UniIdentity& categoryUid,
            const IGraphicsStyleData& graphicsStyleData,
            const CollaborationContext& context
        ) = 0;

        /// \brief 上传协同项目的样式数据。
        ///
        /// 这些样式数据来自于内建的样式数据。
        ///
        /// \param collaborationContext 协同基本信息。包括项目Id、协同影响范围、专业（在影响范围为CollaborationScope::Specialty时有效）
        /// \param categoryGuids 类别的Guid。目前GCMP自动读取本地xml数据库中的类别和对应的样式数据，指定类别Guid即可
        /// \param deleteAllBeforeUpload 上传前是否先删除
        /// \param[out] pErrorMessage 如果传入不为空，发生错误时传出错误信息
        /// \return bool 成功-true；失败-false
        /// \note 只在协同环境下有效，否则返回false
        virtual bool Upload(const CollaborationContext & collaborationContext, const std::set<Guid, GuidComparer> & categoryGuids, bool deleteAllBeforeUpload, std::wstring * pErrorMessage) = 0;

        /// \brief 获取协同项目的样式数据及对应的填充模式、线型数据
        ///
        /// 通过指定项目Id，协同影响范围，类别Guid，可以获取已在云端的项目样式数据。
        ///
        /// \param collaborationContext 协同基本信息。包括项目Id、协同影响范围、专业（在影响范围为CollaborationScope::Specialty时有效）
        /// \param categoryGuid 类别的Guid
        /// \param[out] opGraphicsStyleData 获得的样式数据
        /// \param[out] opLineTypeData 获得的线型数据
        /// \param[out] opFillPatternData  获得的填充数据
        /// \param[out] pErrorMessage 如果传入不为空，发生错误时传出错误信息
        /// \return bool 成功返回true，失败false
        /// \note 只在协同环境下有效，否则返回false
        virtual bool QueryGraphicsStyleData(const CollaborationContext & collaborationContext, const Guid & categoryGuid, OwnerPtr<IGraphicsStyleData> & opGraphicsStyleData, std::vector<OwnerPtr<ILineTypeData>> & opLineTypeData, std::vector<OwnerPtr<IFillPatternData>> & opFillPatternData, std::wstring * pErrorMessage) = 0;
   
        /// \brief 上传协同项目的样式数据。
        ///
        /// 这些样式数据来自于用户自定义的样式数据，同时上传的数据要求协同基本信息一致。
        /// 如果多条插入，全成功算成功。部分成功算失败，但是成功部分已经上传到数据库。
        ///
        /// \param collaborationContext 协同基本信息。包括项目Id、协同影响范围、专业（在影响范围为CollaborationScope::Specialty时有效）
        /// \param CategoryGuidAndGraphicsDataCollection 需要上传的对应CategoryGuid的图像样式数据
        /// \param overrideOldData 是否强制覆盖，true表示强制覆盖；false表示不强制覆盖。
        /// \param deleteAllBeforeUpload 上传前是否先删除
        /// \param[out] pErrorMessage 如果传入不为空，发生错误时传出错误信息
        /// \return bool 成功-true；失败-false
        /// \note 只在协同环境下有效，否则返回false
        virtual bool Upload(
            const CollaborationContext & collaborationContext, 
            const std::map<Guid, const IGraphicsStyleData*, GuidComparer>& categoryGuidAndGraphicsDataCollection,
            bool overrideOldData,
            bool deleteAllBeforeUpload,
            std::wstring * pErrorMessage
        ) = 0;

        /// \brief 上传协同项目的线型数据。
        ///
        /// 这些线型数据来自于用户自定义的样式数据，同时上传的数据要求协同基本信息一致。
        /// 如果多条插入，全成功算成功。部分成功算失败，但是成功部分已经上传到数据库。
        ///
        /// \param collaborationContext 协同基本信息。包括项目Id、协同影响范围、专业（在影响范围为CollaborationScope::Specialty时有效）
        /// \param LineTypeDataCollection 线型数据，IGraphicsStyleData中的线型记录了线型名称，其背后的资源即为该线型数据
        /// \param overrideOldData 是否强制覆盖，true表示强制覆盖；false表示不强制覆盖。
        /// \param deleteAllBeforeUpload 上传前是否先删除
        /// \param[out] pErrorMessage 如果传入不为空，发生错误时传出错误信息
        /// \return bool 成功-true；失败-false
        /// \note 只在协同环境下有效，否则返回false
        virtual bool Upload(
            const CollaborationContext & collaborationContext,
            const std::vector<const ILineTypeData*>& lineTypeDataCollection,
            bool overrideOldData,
            bool deleteAllBeforeUpload,
            std::wstring * pErrorMessage
        ) = 0;

        /// \brief 上传协同项目的填充数据。
        ///
        /// 这些填充数据来自于用户自定义的填充数据，同时上传的数据要求协同基本信息一致。
        /// 如果多条插入，全成功算成功。部分成功算失败，但是成功部分已经上传到数据库。
        ///
        /// \param collaborationContext 协同基本信息。包括项目Id、协同影响范围、专业（在影响范围为CollaborationScope::Specialty时有效）
        /// \param FillPatternDataCollection 填充模式数据，IGraphicsStyleData中的填充模式记录了填充模式名称，其背后的资源即为该填充模式数据
        /// \param overrideOldData 是否强制覆盖，true表示强制覆盖；false表示不强制覆盖。
        /// \param deleteAllBeforeUpload 上传前是否先删除
        /// \param[out] pErrorMessage 如果传入不为空，发生错误时传出错误信息
        /// \return bool 成功-true；失败-false
        /// \note 只在协同环境下有效，否则返回false
        virtual bool Upload(
            const CollaborationContext & collaborationContext,
            const std::vector<const IFillPatternData*>& fillPatternDataCollection,
            bool overrideOldData,
            bool deleteAllBeforeUpload,
            std::wstring * pErrorMessage
        ) = 0;

        /// \brief 批量重载图形样式
        /// 
        /// 所有节点的样式都会被重载，如果IGraphicsNodeStyleAndMaterialOverride中设置图形样式定制器后，该设置的值将不起作用
        /// 注意：此处是批量处理到重载到IGraphicsNodeStyleAndMaterialOverride中
        /// 不要再事务外使用该接口
        /// \param elementIdToStyleId 所需重载的elementId与其对应styleId集合。
        virtual void OverrideGraphicsStyle(const std::map<ElementId, ElementId>& elementIdToStyleId) const = 0;

        /// \brief 批量重载图形样式
        /// 
        /// 所有节点的样式都会被重载，如果IGraphicsNodeStyleAndMaterialOverride中设置图形样式定制器后，该设置的值将不起作用
        /// 注意：此处是批量处理到重载到IGraphicsNodeStyleAndMaterialOverride中
        /// 不要再事务外使用该接口
        /// \param elementIds，待重載的Id集，elementIds中不应该包含临时id
        /// \param styleId 图形样式的 id; 如果 id 是无效的，相当于取消重载图形样式
        virtual void OverrideGraphicsStyle(const std::set<ElementId>& elementIds, const ElementId& styleId) const = 0;

        /// \brief 批量设置图形节点上的标签重载图形样式
        ///
        /// 在所有eleIds上都设置一个Tag并对应styleId
        /// 注意：此处是批量处理到重载到IGraphicsNodeStyleAndMaterialOverride中
        /// 注意：此方法起效，必须是IGraphicsNodeStyleAndMaterialOverride::OverrideGraphicsStyle、IGraphicsNodeStyleAndMaterialOverride中的IGraphicsNodeStyleAndMaterialCustomizer返回的样式id无效
        /// 不要再事务外使用该接口
        /// \param elementIdToGuidAndStyleId 所需重载的elementId与其对应guid，styleId集合。
        GCMP_DEPRECATED_API(2022 / 12 / 30) virtual void OverrideGraphicsStyleByGraphicsNodeTag(const std::map<ElementId, std::vector<std::pair<Guid, ElementId>>>& elementIdToGuidAndStyleId) const = 0;

        /// \brief 批量设置图形节点上的标签重载图形样式
        ///
        /// 在所有eleIds上都设置一个Tag并对应styleId
        /// 注意：此处是批量处理到重载到IGraphicsNodeStyleAndMaterialOverride中
        /// 注意：此方法起效，必须是IGraphicsNodeStyleAndMaterialOverride::OverrideGraphicsStyle、IGraphicsNodeStyleAndMaterialOverride中的IGraphicsNodeStyleAndMaterialCustomizer返回的样式id无效
        /// 不要再事务外使用该接口
        /// \param elementIds，待重載的Id集，elementIds中不应该包含临时id
        /// \param tag 图形节点上的标签
        /// \param styleId 重载图形样式的 id; 如果 id 是无效的，相当于取消图形样式的重载
        GCMP_DEPRECATED_API(2022 / 12 / 30) virtual void OverrideGraphicsStyleByGraphicsNodeTag(const std::set<ElementId>& elementIds, const Guid &tag, const ElementId &styleId) const = 0;
    };
}
